﻿using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mail;
using System.Net.Mime;
using RazorEngine;
using Wolfpack.Core;

namespace Wolfpack.Contrib.Publishers.Email
{
    public class HtmlSmtpUtility : SmtpUtility
    {
        public HtmlSmtpUtility(EmailConfiguration configuration)
            : base(configuration)
        {
        }

        public override bool IsHtml
        {
            get { return true; }
        }

        public override bool GetHtmlView(NotificationModel model, out AlternateView view)
        {
            string templatefile;

            view = null;

            if (GetTemplateFilename(model, "html", out templatefile))
            {
                var template = File.ReadAllText(templatefile);
                var content = Razor.Parse(template, model);

                view = AlternateView.CreateAlternateViewFromString(content, null, MediaTypeNames.Text.Html);
                AddImages(content, view);
                AddCss(content, view);
            }

            return view != null;
        }

        public override bool GetTextView(NotificationModel model, out AlternateView view)
        {
            string templatefile;

            view = null;

            if (GetTemplateFilename(model, "txt", out templatefile))
            {
                var template = File.ReadAllText(templatefile);
                var content = Razor.Parse(template, model);

                view = AlternateView.CreateAlternateViewFromString(content, null, MediaTypeNames.Text.Plain);
            }

            return view != null;
        }

        private void AddImages(string templateContent, AlternateView avHtml)
        {
            var imagesFolder = SmartLocation.GetLocation(Path.Combine(Configuration.TemplatePath, "images"));

            if (!Directory.Exists(imagesFolder))
            {
                Logger.Warning("Folder '{0}' containing email publisher images does not exist!", imagesFolder);
                return;
            }

            foreach (var itemPath in Directory.GetFiles(imagesFolder))
            {
                var extension = Path.GetExtension(itemPath) ?? string.Empty;
                var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(itemPath);

                if (!templateContent.Contains("cid:" + fileNameWithoutExtension))
                    continue;

                var mediaType = string.Empty;

                switch (extension.ToLower())
                {
                    case ".png":
                        mediaType = "image/png";
                        break;
                    case ".gif":
                        mediaType = MediaTypeNames.Image.Gif;
                        break;
                    case ".jpg":
                        mediaType = MediaTypeNames.Image.Jpeg;
                        break;
                    case ".tif":
                        mediaType = MediaTypeNames.Image.Tiff;
                        break;
                }

                var image = new LinkedResource(itemPath, mediaType)
                                {
                                    ContentId = fileNameWithoutExtension,
                                };
                avHtml.LinkedResources.Add(image);
            }
        }


        private void AddCss(string content, AlternateView avHtml)
        {
            var cssFolder = Path.Combine(Configuration.TemplatePath, "css");

            if (!Directory.Exists(cssFolder))
                return;

            foreach (var stylesheet in from itemPath in Directory.GetFiles(cssFolder)
                                       let fileNameWithoutExtension = Path.GetFileNameWithoutExtension(itemPath)
                                       where content.Contains("cid:" + fileNameWithoutExtension)
                                       select new LinkedResource(itemPath, "text/css")
                                                     {
                                                         ContentId = fileNameWithoutExtension
                                                     })
            {
                avHtml.LinkedResources.Add(stylesheet);
            }
        }

        private bool GetTemplateFilename(NotificationModel model, string type, out string templatepath)
        {
            var probingPaths = new List<string>
                                   {
                                       model.CheckId,
                                       "Default"
                                   };

            templatepath = probingPaths.Select(
                t => SmartLocation.GetLocation(Path.Combine(Configuration.TemplatePath, 
                    string.Format("{0}.{1}.cshtml", t, type))))
                .FirstOrDefault(File.Exists);

            return !string.IsNullOrWhiteSpace(templatepath) && File.Exists(templatepath);
        }
    }
}